#include "unitconversionmanager.h"
#include "datamanager.h"
#include "map.h"
#include "utility.h"

namespace VrDataCore
{
	UnitConversionManager* UnitConversionManager::_unitConversionManager = NULL;

	UnitConversionManager::UnitConversionManager()
	{
		resetConversion();
		_referenceUnitConversion = "";
	}

	UnitConversionManager::~UnitConversionManager()
	{}

	bool UnitConversionManager::testReferenceUnitConversion()
	{
		QString ruc = DataManager::GetInstance().getCurrentMap()->getReferenceUnitConversion();
		if(ruc == "")
		{
			_referenceUnitConversion = "";
			return false;
		}
		if(ruc!=_referenceUnitConversion)
		{
			//change map
			QStringList valuelist = ruc.split(" ",QString::SkipEmptyParts);
			if(valuelist.size() == 4)
			{
				double minsx = valuelist.at(0).toDouble();
				double minsy = valuelist.at(1).toDouble();
				double minrx = valuelist.at(2).toDouble();
				double minry = valuelist.at(3).toDouble();
				resetConversion();
				addConverReferencePointD(minsx,minsy,minrx,minry,false);
				_referenceUnitConversion = ruc;
				return true;
			}
			else
			{
				_referenceUnitConversion = "";
				return false;
			}
		}
		return true;
	}

	UnitConversionManager& UnitConversionManager::GetInstance()
	{
		if(_unitConversionManager == NULL)
			_unitConversionManager = new UnitConversionManager();
		return *_unitConversionManager;
	}

	void UnitConversionManager::resetConversion()
	{
		_minSet._realWorldX = 0;
		_minSet._realWorldY = 0;
		_minSet._sceneWorldX = FLT_MAX;
		_minSet._sceneWorldY = FLT_MAX;
	}

	void UnitConversionManager::addConverReferencePointD(double sceneworldx,double sceneworldy,double realworldx,
		double realworldy,bool updatemap)
	{
		_minSet._realWorldX = realworldx;
		_minSet._realWorldY = realworldy;
		_minSet._sceneWorldX = sceneworldx;
		_minSet._sceneWorldY = sceneworldy;
		if(updatemap)
			updateMap();
	}

	void UnitConversionManager::addConverReferencePointDMS(double sceneworldx,double sceneworldy,int realworldxd,int realworldxm,
		int realworldxds,int realworldyd,int realworldym,int realworldyds,bool updatemap)
	{

		_minSet._sceneWorldX = sceneworldx;
		_minSet._realWorldX = conversionDMS_TO_D(realworldxd,realworldxm,realworldxds);
		_minSet._sceneWorldY = sceneworldy;
		_minSet._realWorldY = conversionDMS_TO_D(realworldyd,realworldym,realworldyds);
		if(updatemap)
			updateMap();
	}

	void UnitConversionManager::updateMap()
	{
		_referenceUnitConversion = QString::number(_minSet._sceneWorldX,'g',21);
		_referenceUnitConversion.append(" ");
		_referenceUnitConversion.append(QString::number(_minSet._sceneWorldY,'g',21));
		_referenceUnitConversion.append(" ");
		_referenceUnitConversion.append(QString::number(_minSet._realWorldX,'g',21));
		_referenceUnitConversion.append(" ");
		_referenceUnitConversion.append(QString::number(_minSet._realWorldY,'g',21));
		VrDataCore::DataManager::GetInstance().getCurrentMap()->setReferenceUnitConversion(_referenceUnitConversion);
	}

	void UnitConversionManager::getAfterConverPointSTR(double sceneworldx,double sceneworldy,double& realworldx,double& realworldy)
	{
		//if(testReferenceUnitConversion())
		//{
		//	realworldx = (sceneworldx - _minSet._sceneWorldX)*_xReference + _minSet._realWorldX;
		//	realworldy = (sceneworldy - _minSet._sceneWorldY)*_yReference + _minSet._realWorldY;
		//	return;
		//}
		realworldx = sceneworldx;
		realworldy = sceneworldy;
	}

	void UnitConversionManager::getAfterConverPointRTS(double& sceneworldx,double& sceneworldy,double realworldx,double realworldy)
	{
		if(testReferenceUnitConversion())
		{
			float yoff = getEarthDistanceLNG(_minSet._realWorldX,_minSet._realWorldY,realworldx,realworldy);
			float xoff = getEarthDistanceLAT(_minSet._realWorldX,_minSet._realWorldY,realworldx,realworldy);

			sceneworldx = _minSet._sceneWorldX + xoff;
			sceneworldy = _minSet._sceneWorldY + yoff;
			return;
		}
		sceneworldx = realworldx;
		sceneworldy = realworldy;
	}
}